﻿
Imports System.Runtime.CompilerServices

Public Class binder(Of T As Class)
    Inherits binder(Of T, Object)
End Class

Public Module _binder
    <Extension()> Public Function has_value(Of T As Class, PROTECTION) _
                                           (ByVal i As binder(Of T, PROTECTION)) As Boolean
        Return (Not i Is Nothing AndAlso i.has_local_value()) OrElse
               binder(Of T, PROTECTION).has_global_value()
    End Function
End Module

Public Class binder(Of T As Class, PROTECTION)
    Private Shared ReadOnly is_protected As Boolean
    Private Shared _global As T
    Private _local As T

    Shared Sub New()
        is_protected = (Not GetType(PROTECTION) Is GetType(Object))
    End Sub

    Public Sub set_local(ByVal i As T)
        _local = i
    End Sub

    Public Shared Sub set_global(ByVal i As T)
        _global = i
    End Sub

    Public Shared Function [global]() As T
        If _global Is Nothing AndAlso is_protected Then
            Return binder(Of T).global()
        Else
            Return _global
        End If
    End Function

    Public Function local() As T
        Return _local
    End Function

    Public Shared Function has_global_value() As Boolean
        Return Not [global]() Is Nothing
    End Function

    Public Function has_local_value() As Boolean
        Return Not local() Is Nothing
    End Function

    Public Function [get]() As T
        If has_local_value() Then
            Return local()
        Else
            Return [global]()
        End If
    End Function

    Public Shared Operator +(ByVal this As binder(Of T, PROTECTION)) As T
        If this Is Nothing Then
            Return [global]()
        Else
            Return this.get()
        End If
    End Operator
End Class
